﻿using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel;
using System.Net.NetworkInformation;
using System.Numerics;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace BridgeAgent
{
    public class Class1
    {
        //用户启动软件并导入了路线
        //用户提问,例如：帮我建一个4*30的双幅桥，这个桥的中心桩号等于3960，并显示它的桥型布置图
        //根据问题去向量库中匹配最相关的5条数据，得到“匹配知识”
        //给AI一些提示词（提示词的目的要达成AI的输出格式化），然后连同用户的问题、“匹配知识”、“运行流程中产生的中间数据”一起丢给AI
        //AI的回答是格式的：
        //  根据格式可以知道AI是否需要调用工具以及调用工具所提供的参数

        public Kernel Kernel { get; set; }

        /// <summary>
        /// 聊天记录
        /// </summary>
        public ChatHistory ChatHistory { get; set; }

        public Class1()
        {
            IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
            #pragma warning disable SKEXP0010
            kernelBuilder.AddOpenAIChatCompletion("glm-4-plus", new Uri("https://open.bigmodel.cn/api/paas/v4"), "7820e6fcff82c71549f783bb82fc8ffc.uFJw6bI7Qa0NCtf9");
            Kernel = kernelBuilder.Build();
            ChatHistory = new ChatHistory();
        }

        public List<string> GetTools()
        {
            string tool1 = @"
        /// <summary>
        /// 查询指定城市的现在的气温
        /// </summary>
        /// <param name=""cityName"">城市名称</param>
        /// <returns>返回气温</returns>
        public string GetCityTemperature(string cityName)";
            return new List<string>() { tool1 };
        }
        //帮我写出城市的英文名
        public string GetCityName(string cityName)
        {
            return cityName;
        }
        /// <summary>
        /// 查询指定城市的现在的气温
        /// </summary>
        /// <param name="cityName">城市名称</param>
        /// <returns>返回气温</returns>
        public string GetCityTemperature(string cityName)
        {
            return cityName + "现在的气温是21°";
        }

        /// <summary>
        /// 向agent提问
        /// </summary>
        /// <param name="questions">问题</param>
        /// <param name="action">字符流的回调函数</param>
        /// <returns></returns>
        public async Task<string> Questions(string questions,Action<string> action)
        {
            int i = 10;
            string key0 = "最终结果:";
            string key1 = "需要调用工具:";
            string systemPrompt = @"
                你是一个AI助手，你的名字是BridgeAI，你的任务是帮助用户解决各种问题。
                你可以使用工具来帮助用户解决问题,也可以根据<data></data>标签中的已知信息来解决问题。当你需要用到工具时你的回答应该按照以下格式回答：
                "+ key1 + @"[""GetCityTemperature"",""北京""]
                当你不需要调用工具时你的回答应该按照以下格式回答：
                "+key0+@"你的回答。";
            List<string> list = GetTools();
            string tools = "<Tools></Tools>在这个标记区间的是你可以使用的工具，";
            tools += "<Tools>";
            list.ForEach(x=> tools+=x);
            tools += "</Tools>";
            systemPrompt += tools;
            systemPrompt += "<data></data>";
            string msg = "";
            while (i > 0)
            {
                msg = "";
                var chatHistory = new ChatHistory();
                chatHistory.AddSystemMessage(systemPrompt);
                chatHistory.AddUserMessage(questions);
                var matchedData = MatchedDataVectorDatabase(questions);
                //chatHistory[0].Content = $"{systemPrompt}\n\nLong term memory:\n{matchedData}";
                msg = await AskAIQuestions(chatHistory, (string content) =>
                {
                    msg += content;
                    if (msg.Length < 10)
                    {
                        if (msg.Contains(key0))
                        {
                            action(content);
                        }
                    }
                });
                i--;
                if (msg.Substring(0,key0.Length).Contains(key0))
                {
                    return msg;
                }
                else if (msg.Substring(0, key1.Length).Contains(key1))
                {
                    string v = msg.Substring(key1.Length, msg.Length - key1.Length);
                    List<string>? list1 = JsonConvert.DeserializeObject<List<string>>(v);
                    string v1 = GetCityTemperature(list1[1]);
                    systemPrompt = systemPrompt.Insert(systemPrompt.Length-7, v1);
                    // 调用工具
                }
            }
            return msg;
        }


        /// <summary>
        /// 去向量数据库中匹配最接近的5条数据
        /// </summary>
        /// <param name="texx"></param>
        /// <returns></returns>
        public List<string> MatchedDataVectorDatabase(string texx)
        {
            //var chatService = Kernel.GetRequiredService<IChatCompletionService>();
            //var memory = (new QdrantService()).GetKernelMemory();
            //var longTermMemory = await GetLongTermMemory(memory, Input.Text);
            //chatHistory.AddUserMessage(questions);
            //chatHistory[0].Content = $"{systemPrompt}\n\nLong term memory:\n{longTermMemory}";
            return new List<string>();
        }
        /// <summary>
        /// 向AI提问
        /// </summary>
        /// <param name="chatHistory">聊天记录</param>
        /// <param name="action">字符流回调函数</param>
        /// <returns></returns>
        public async Task<string> AskAIQuestions(ChatHistory chatHistory,Action<string> action)
        {
            //task.Result可以拿值
            var chatService = Kernel.GetRequiredService<IChatCompletionService>();
            string msg = "";
            await foreach (StreamingChatMessageContent chatUpdate in chatService.GetStreamingChatMessageContentsAsync(chatHistory))
            {
                if (chatUpdate.Content is { Length: > 0 })
                {
                    msg += chatUpdate.Content;
                    action(chatUpdate.Content);
                    Thread.Sleep(10);
                }
            }
            return msg;
        }
    }
}
